package handler

import (
	"fmt"
	"gopatch/file"
	"gopatch/global"
	"path/filepath"
	"strings"
)

// 开启自动匹配的处理类
type autoCompareHandler struct{}

func (a *autoCompareHandler) judgeHandler() bool {
	if global.AutoCompare {
		return true
	}
	return false
}

func (a *autoCompareHandler) chooseFile(gitUpdateFile, filenameWithoutExt string, sameNameFiles []file.FileStruct) []file.FileStruct {
	// 得到的补丁文件绝对路径
	var patchFiles []file.FileStruct

	if sameNameFiles == nil || len(sameNameFiles) <= 0 {
		// 没有得到对应的文件
		global.AppendMsg(global.ERROR, fmt.Sprintf("文件 %s 没有找到对应的", filenameWithoutExt))
	} else if len(sameNameFiles) == 1 {
		// 得到的文件只有一个，直接放进去
		fileT := sameNameFiles[0]
		patchFiles = append(patchFiles, fileT)
	} else {
		// 得到的文件很多，先进行自动匹配
		autoCompareFileAbsPaths := autoCompare(gitUpdateFile, sameNameFiles)

		if autoCompareFileAbsPaths != nil && len(autoCompareFileAbsPaths) > 0 {
			if global.SkipConfirm {
				// 跳过确认阶段，那就直接放进入
				patchFiles = append(patchFiles, autoCompareFileAbsPaths...)
			} else {
				// 手动进行确认
				// 如果只有一个，那也直接放进去
				if len(autoCompareFileAbsPaths) == 1 {
					patchFiles = append(patchFiles, autoCompareFileAbsPaths[0])
				} else {
					chooseUpdateFiles := handleInput(filenameWithoutExt, autoCompareFileAbsPaths)
					patchFiles = append(patchFiles, chooseUpdateFiles...)
				}
			}
		} else {
			global.AppendMsg(global.ERROR, fmt.Sprintf("文件 %s 没有自动匹配到文件", gitUpdateFile))
		}
	}

	return patchFiles
}

// 自动向上匹配目录，得到疑似的待复制文件
func autoCompare(targetFilePath string, findAllFiles []file.FileStruct) []file.FileStruct {

	// 替换 .java 后缀为 .class
	if strings.EqualFold(filepath.Ext(targetFilePath), ".java") {
		targetFilePath = strings.Replace(targetFilePath, ".java", ".class", 1)
	}
	// 对 targetFilePath 的目录分隔符进行转换
	targetFilePath = strings.ReplaceAll(targetFilePath, "/", "\\")
	// 反转字符
	targetFilePathReverse := reverseString(targetFilePath)

	maxMatch := 0
	// key-匹配成功的字符串长度, val-文件绝对路径集合
	var matchCount2FilesAbsPath = make(map[int][]file.FileStruct)
	for _, findAllFile := range findAllFiles {
		findAllFileAbsPathReverse := reverseString(findAllFile.AbsFilePath)
		matchLen := 0

		rune1 := []rune(targetFilePathReverse)
		rune2 := []rune(findAllFileAbsPathReverse)
		for i := 0; i < len(rune1) && i < len(rune2); i++ {
			r1 := rune1[i]
			r2 := rune2[i]
			if r1 == r2 {
				if r1 == '\\' {
					// 只有是目录分隔符时才算匹配一级
					matchLen++
				}
			} else {
				break
			}
		}

		fileAbsPaths := matchCount2FilesAbsPath[matchLen]
		if fileAbsPaths == nil {
			fileAbsPaths = []file.FileStruct{}
		}
		fileAbsPaths = append(fileAbsPaths, findAllFile)
		matchCount2FilesAbsPath[matchLen] = fileAbsPaths

		if matchLen > maxMatch {
			maxMatch = matchLen
		}
	}

	// TODO 如果匹配成功的次数只有一个，那应该认为没有匹配成功吗

	// 拿到匹配次数最多的 slice
	return matchCount2FilesAbsPath[maxMatch]
}

func reverseString(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}
